const GeneralUtils = {};

/**
 * 是否为空
 * @param obj
 * @returns {boolean}
 */
GeneralUtils.isEmpty = (obj) => {
  if (obj == null) {
    return true;
  }
  const type = typeof obj;
  switch (type) {
    case 'string':
      return obj.length == 0;
    case 'object':
      if (obj instanceof Date) {
        return isNaN(obj.getTime());
      }
      if (obj instanceof Array) {
        return obj.length == 0;
      }
      return Object.keys(obj).length == 0;
    case "number":
      return isNaN(obj);
    default:
      break;
  }
  return false;
};

/**
 * 是否非空
 * @param obj
 * @returns {boolean}
 */
GeneralUtils.isNotEmpty = (value) => {
  return !GeneralUtils.isEmpty(value);
};

/**
 * 是否为空字符
 * @param {string} obj
 * @returns {boolean}
 */
GeneralUtils.isBlank = (obj) => {
  if (obj == null) {
    return true;
  }
  if (typeof obj == 'string') {
    return obj.trim() == '' || obj.trim() == 'null';
  }
  return false;
};

/**
 * 是否非空字符
 * @param {string} obj
 * @returns {boolean}
 */
GeneralUtils.isNotBlank = (obj) => {
  return !GeneralUtils.isBlank(obj);
};

/**
 * 转为Date对象
 * @param {string|number|Date} date 
 * @returns {Date}
 */
GeneralUtils.parserDate = (obj) => {
  let date = null;
  if (typeof obj === 'string') {
    // ios 无法解析 yyyy-MM-dd HH:mm:ss 格式，改为 yyyy/MM/dd HH:mm:ss
    date = new Date(obj.replaceAll('T', ' ').replaceAll('-', '/'));
  }
  date = new Date(obj);
  if (isNaN(date.getTime())) {
    return null;
  }
  return date;
}

/**
 * 格式化日期
 * @param date          默认当前时间
 * @param isNeedTime    是否需要追加时分秒
 * @param replaceSymbol 是否替换符号
 * @returns {string} yyyy-MM-dd | yyyy-MM-dd HH:mm:ss | yyyyMMdd | yyyyMMddHHmmss
 */
GeneralUtils.formatDate = (date, isNeedTime, replaceSymbol) => {
  if (!date) {
    date = new Date();
  } else {
    if (typeof date === 'string') {
      // ios 无法解析 yyyy-MM-dd HH:mm:ss 格式
      date = date.replaceAll('T', ' ').replaceAll('-', '/');
    }
    date = GeneralUtils.parserDate(date);
  }
  const year = date.getFullYear();
  let month = (date.getMonth() + 1).toString();
  month = month.length > 1 ? month : '0' + month;
  let day = date.getDate().toString();
  day = day.length > 1 ? day : '0' + day;
  let hours = date.getHours().toString();
  hours = hours.length > 1 ? hours : '0' + hours;
  let minutes = date.getMinutes().toString();
  minutes = minutes.length > 1 ? minutes : '0' + minutes;
  let seconds = date.getSeconds().toString();
  seconds = seconds.length > 1 ? seconds : '0' + seconds;
  let dateStr = year + "-" + month + "-" + day;
  if (isNeedTime) {
    dateStr += " " + hours + ":" + minutes + ":" + seconds;
  }
  if (replaceSymbol) {
    dateStr = dateStr.replace(/[-: ]/g, '');
  }
  return dateStr;
};


/**
 * 获取当天时间字符串
 * @returns {string} yyyy-MM-dd
 */
GeneralUtils.getCurrentDateStr = () => {
  return GeneralUtils.formatDate(new Date(), false, false);
}

/**
 * 获取当天时间字符串
 * @returns {string} yyyy-MM-dd
 */
GeneralUtils.getCurrentTimeStr = () => {
  return GeneralUtils.formatDate(new Date(), true, false);
}


/**
 * 获取日期范围字符串数组 [yyyyMMdd...]
 * @param startDate
 * @param endDate
 * @param replaceSymbol 字符串是否替换'-'符号
 * @returns {*[]}
 */
GeneralUtils.getDateRange = (startDate, endDate, replaceSymbol) => {
  startDate = new Date(startDate);
  endDate = new Date(endDate);
  let dateRangeList = [];
  while (startDate <= endDate) {
    dateRangeList.push(GeneralUtils.formatDate(startDate, false, replaceSymbol));
    startDate.setDate(startDate.getDate() + 1);
  }
  return dateRangeList;
}

/**
 * 获取最近x天的日期字符串数组
 * @param dayNum
 * @returns {*[]}
 */
GeneralUtils.getLastNDays = (dayNum) => {
  const today = new Date();
  today.setHours(0, 0, 0, 0);
  let days = [];
  // 循环dayNum次，每次向前推一天
  for (let i = 0; i < dayNum; i++) {
    // 向前推i天
    today.setDate(today.getDate() - 1);
    days.push(GeneralUtils.formatDate(today, false, true));
  }
  return days;
}

/**
 * 生成唯一ID（32位)
 */
GeneralUtils.uuid = () => {
  return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, (s) => {
    const random = Math.random() * 16 | 0;
    return (s == 'x' ? random : random & 0x3 | 0x8).toString(16);
  });
}

/**
 * 生成链路ID（30位：16位uuid + yyyyMMddHHmmss)
 */
GeneralUtils.buildTraceId = () => {
  return 'xxxxxxxxxxxx4xxx'.replace(/[xy]/g, (s) => {
    const random = Math.random() * 16 | 0;
    return (s == 'x' ? random : random & 0x3 | 0x8).toString(16);
  }) + "-" + GeneralUtils.formatDate(new Date(), true, true);
}

/**
 * 深克隆对象
 * @param {object} data
 * @returns {string|*}
 */
GeneralUtils.cloneDeep = (data) => {
  if (GeneralUtils.isEmpty(data)) {
    return data;
  }
  return JSON.parse(JSON.stringify(data));
}

/**
 * 获取随机数
 * @param min
 * @param max
 * @returns {number}
 */
GeneralUtils.getRandomInt = (min, max) => {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

module.exports = GeneralUtils;